/**
 * Copyright (c) 2008, Andrew Carter
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without modification, are 
 * permitted provided that the following conditions are met:
 * 
 * Redistributions of source code must retain the above copyright notice, this list of 
 * conditions and the following disclaimer. Redistributions in binary form must reproduce 
 * the above copyright notice, this list of conditions and the following disclaimer in 
 * the documentation and/or other materials provided with the distribution. Neither the 
 * name of Andrew Carter nor the names of contributors may be used to endorse or promote 
 * products derived from this software without specific prior written permission. 
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
 * SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 
 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
package com.acarter.scenemonitor.propertydescriptor.editor;

import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;

import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;

import com.jme.math.Vector3f;

/**
 * 
 * @author Andrew Carter
 */
public class Vector3fEditorPanel extends A_EditorPanel {

	/**	 */
	private static final long serialVersionUID = 1L;
	
	/**  */
	private JDialog dialog = null;
	
	/**  */
	private Vector3f vector;
	
	/**  */
	private Vector3f vRestore;

	/**  */
	private JTextField componentX;

	/**  */
	private JTextField componentY;

	/**  */
	private JTextField componentZ;

	/**  */
	private JButton xSlider;

	/**  */
	private JButton ySlider;

	/**  */
	private JButton zSlider;
	
	/**  */
	private JButton cancel;
	
	/**  */
	private JButton done;
	
	/**  */
	private int labelPad = -1;

	/**
	 * 
	 * @param label 
	 * @param vector 
	 * @param state
	 */
	public Vector3fEditorPanel(JDialog dialog, Vector3f vector) {

		this.dialog = dialog;
		this.vector = vector;
		
		vRestore = new Vector3f(vector);
		
		build();
		initValues();
	}

	/**
	 * 
	 * @param label 
	 * @param vector 
	 * @param labelPad 
	 * @param state
	 */
	public Vector3fEditorPanel(JDialog dialog, Vector3f vector, int labelPad) {

		this.dialog = dialog;
		this.vector = vector;
		this.labelPad = labelPad;
		
		vRestore = new Vector3f(vector);
		
		build();
		initValues();
	}

	/**
	 * 
	 * @param label 
	 * @param vector 
	 * @param labelPad 
	 * @param state
	 */
	public Vector3fEditorPanel(JDialog dialog, Vector3f vector, int labelPad, int fieldWidth) {

		this.dialog = dialog;
		this.vector = vector;
		this.labelPad = labelPad;
		fieldDim.setSize(fieldWidth, fieldDim.getHeight());

		vRestore = new Vector3f(vector);
		
		build();
		initValues();
	}

	/**
	 * 
	 *
	 */
	private void build() {

		JLabel labelX = new JLabel("X: ");
		labelX.setFont(font);

		componentX = new JTextField();
		componentX.setFont(font);
		componentX.setPreferredSize(fieldDim);
		componentX.setMaximumSize(componentX.getPreferredSize());

		xSlider = new JButton();
		xSlider.setPreferredSize(sliderDim);
		xSlider.setMaximumSize(xSlider.getPreferredSize());
		xSlider.setToolTipText(sliderTooltip);

		JLabel labelY = new JLabel("Y: ");
		labelY.setFont(font);

		componentY = new JTextField();
		componentY.setFont(font);
		componentY.setPreferredSize(fieldDim);
		componentY.setMaximumSize(componentY.getPreferredSize());

		ySlider = new JButton();
		ySlider.setPreferredSize(sliderDim);
		ySlider.setMaximumSize(ySlider.getPreferredSize());
		ySlider.setToolTipText(sliderTooltip);

		JLabel labelZ = new JLabel("Z: ");
		labelZ.setFont(font);

		componentZ = new JTextField();
		componentZ.setFont(font);
		componentZ.setPreferredSize(fieldDim);
		componentZ.setMaximumSize(componentZ.getPreferredSize());

		zSlider = new JButton();
		zSlider.setPreferredSize(sliderDim);
		zSlider.setMaximumSize(zSlider.getPreferredSize());
		zSlider.setToolTipText(sliderTooltip);

		done = new JButton("Done");
		done.setFont(font);
		done.setPreferredSize(new Dimension(42, 15));
		done.setMaximumSize(done.getPreferredSize());
		done.setMargin(insets);

		cancel = new JButton("Cancel");
		cancel.setFont(font);
		cancel.setPreferredSize(new Dimension(42, 15));
		cancel.setMaximumSize(cancel.getPreferredSize());
		cancel.setMargin(insets);

		JPanel buttonPanel = new JPanel();
		buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.X_AXIS));
		buttonPanel.add(done);
		buttonPanel.add(Box.createRigidArea(new Dimension(5, 0)));
		buttonPanel.add(cancel);
		buttonPanel.add(Box.createRigidArea(new Dimension(1, 0)));

		JPanel buttonPanel2 = new JPanel();
		buttonPanel2.setLayout(new BoxLayout(buttonPanel2, BoxLayout.Y_AXIS));
		buttonPanel2.add(Box.createGlue());
		buttonPanel2.add(buttonPanel);
		buttonPanel2.add(Box.createGlue());
		
		setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
		
		if(labelPad != -1){
			add(Box.createRigidArea(new Dimension(labelPad, 0)));
		}
		else {
			add(Box.createRigidArea(new Dimension(1, 0)));
			add(Box.createGlue());
		}
		
		add(labelX);
		add(componentX);
		add(xSlider);
		add(Box.createRigidArea(new Dimension(5, 0)));
		add(labelY);
		add(componentY);
		add(ySlider);
		add(Box.createRigidArea(new Dimension(5, 0)));
		add(labelZ);
		add(componentZ);
		add(zSlider);
		add(Box.createRigidArea(new Dimension(5, 0)));
		add(buttonPanel2);

		if(labelPad != -1)
			add(Box.createGlue());
		
		// listeners
		componentX.addActionListener(new ActionListener() {

			public void actionPerformed(ActionEvent evt) {
				onUpdate();
			}
		});
		
		componentX.addKeyListener(new KeyListener() {

			public void keyPressed(KeyEvent e) {
			}

			public void keyReleased(KeyEvent e) {
				onUpdate();
			}

			public void keyTyped(KeyEvent e) {
			}
			
		});
		
		xSlider.addMouseMotionListener(new MouseMotionListener() {

			public void mouseDragged(MouseEvent e) {
				
				vector.x = slideValue(e, vector.x, 100);
				
				initValues();
				
				if(callback != null)
					callback.componentModifiedCallback();
			}

			public void mouseMoved(MouseEvent e) {				
			}
		});
		
		componentY.addActionListener(new ActionListener() {

			public void actionPerformed(ActionEvent evt) {
				onUpdate();
			}
		});
		
		componentY.addKeyListener(new KeyListener() {

			public void keyPressed(KeyEvent e) {
			}

			public void keyReleased(KeyEvent e) {
				onUpdate();
			}

			public void keyTyped(KeyEvent e) {
			}
			
		});
		
		ySlider.addMouseMotionListener(new MouseMotionListener() {

			public void mouseDragged(MouseEvent e) {
				
				vector.y = slideValue(e, vector.y, 100);
				
				initValues();
				
				if(callback != null)
					callback.componentModifiedCallback();
			}

			public void mouseMoved(MouseEvent e) {
			}
		});

		componentZ.addActionListener(new ActionListener() {

			public void actionPerformed(ActionEvent evt) {
				onUpdate();
			}
		});
		
		componentZ.addKeyListener(new KeyListener() {

			public void keyPressed(KeyEvent e) {
			}

			public void keyReleased(KeyEvent e) {
				onUpdate();
			}

			public void keyTyped(KeyEvent e) {
			}
			
		});
		
		zSlider.addMouseMotionListener(new MouseMotionListener() {

			public void mouseDragged(MouseEvent e) {
				
				vector.z = slideValue(e, vector.z, 100);
				
				initValues();
				
				if(callback != null)
					callback.componentModifiedCallback();
			}

			public void mouseMoved(MouseEvent e) {				
			}
		});

		done.addActionListener(new ActionListener() {

			public void actionPerformed(ActionEvent evt) {

				dialog.setVisible(false);
			}
		});

		cancel.addActionListener(new ActionListener() {

			public void actionPerformed(ActionEvent evt) {

				restoreValue();

				dialog.setVisible(false);
			}
		});
	}

	/**
	 * 
	 * 
	 */
	public void initValues() {

		componentX.setText(Float.toString(vector.x));
		componentY.setText(Float.toString(vector.y));
		componentZ.setText(Float.toString(vector.z));
	}
	
	/**
	 * 
	 */
	public void restoreValue() {
		
		vector.set(vRestore);
		
		if(callback != null)
			callback.componentModifiedCallback();
	}
	
	/**
	 * 
	 *
	 */
	private void onUpdate() {

		float x = vector.x;
		float y = vector.y;
		float z = vector.z;

		x = toFloat(componentX.getText(), x);
		y = toFloat(componentY.getText(), y);
		z = toFloat(componentZ.getText(), z);

		vector.set(x, y, z);
		
		if(callback != null)
			callback.componentModifiedCallback();
	}
	
	@Override
	public void setEnabled(boolean enabled)
	{
		super.setEnabled(enabled);
		
		componentX.setEnabled(enabled);
		componentY.setEnabled(enabled);
		componentZ.setEnabled(enabled);
		
		xSlider.setEnabled(enabled);
		ySlider.setEnabled(enabled);
		zSlider.setEnabled(enabled);
	}
}
